package com.xz.purchase.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xz.audit.domain.ProcessInstance;
import com.xz.audit.dto.AuditDto;
import com.xz.audit.dto.AuditInfoDto;
import com.xz.audit.service.IAuditProcessService;
import com.xz.audit.service.IProcessInstanceService;
import com.xz.audit.service.impl.AuditInfoServiceImpl;
import com.xz.common.annotation.DataScope;
import com.xz.common.core.domain.AjaxResult;
import com.xz.common.core.domain.model.LoginUser;
import com.xz.common.exception.ServiceException;
import com.xz.common.utils.DateUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xz.common.utils.RedisCode;
import com.xz.common.utils.SecurityUtils;
import com.xz.process.service.IProcessOrderItemService;
import com.xz.purchase.domain.*;
import com.xz.purchase.mapper.PurchaseProductMapper;
import com.xz.purchase.service.IPurchaseProductService;
import com.xz.purchase.service.IReportDamageProductService;
import com.xz.purchase.vo.ReportDamageInfoVo;
import com.xz.purchase.vo.ReportDamageVo;
import com.xz.repertory.service.IRepertoryFlowService;
import com.xz.warehouse.domain.Warehouse;
import com.xz.warehouse.service.IWarehouseService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xz.purchase.mapper.ReportDamageMapper;
import com.xz.purchase.service.IReportDamageService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 库存报损Service业务层处理
 *
 * @author xz
 * @date 2024-01-16
 */
@Service
public class ReportDamageServiceImpl extends ServiceImpl<ReportDamageMapper, ReportDamage> implements IReportDamageService {
    @Autowired
    private ReportDamageMapper reportDamageMapper;
    @Autowired
    private IAuditProcessService iAuditProcessService;
    @Autowired
    private IReportDamageProductService iReportDamageProductService;
    @Autowired
    private IProcessInstanceService processInstanceService;
    @Autowired
    private IPurchaseProductService iPurchaseProductService;
    @Autowired
    private IWarehouseService iWarehouseService;
    @Autowired
    private IRepertoryFlowService iRepertoryFlowService;
    @Autowired
    private PurchaseProductMapper purchaseProductMapper;
    @Autowired
    private IProcessOrderItemService iProcessOrderItemService;
    /**
     * 查询库存报损
     *
     * @param id 库存报损主键
     * @return 库存报损
     */
    @Override
    public ReportDamageInfoVo selectReportDamageById(Long id) {
        return reportDamageMapper.selectReportDamageById(id);
    }

    /**
     * 查询库存报损列表
     *
     * @param reportDamage 库存报损
     * @return 库存报损
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<ReportDamageVo> selectReportDamageList(ReportDamage reportDamage) {
        List<ReportDamageVo> reportDamageList = reportDamageMapper.selectReportDamageList(reportDamage);
        List<ProcessInstance> auditInfoList = processInstanceService.list(new QueryWrapper<ProcessInstance>().ne("audit_status", 2).eq("biz_type",2));
        reportDamageList.stream().forEach(item->{
            if(item.getStatus()==3) {
                ProcessInstance auditInfo = processInstanceService.iAuditInfoService(null, item.getId(), SecurityUtils.getLoginUser().getUser(), auditInfoList);
                if (Objects.nonNull(auditInfo)) {
                    if (auditInfo.getAuditBut() != null) {
                        item.setAuditBut(auditInfo.getAuditBut());
                    }
                    item.setAuditName(auditInfo.getNodeName());
                    //流程状态（1.待审核 2.已完成 3.已驳回 4.重新发起）
                    item.setAuditType(auditInfo.getAuditStatus());
                }
            }
            if(item.getStatus()==4){
                if(SecurityUtils.getUsername().equals(item.getUserName())){
                    item.setAuditBut(3);
                    item.setAuditType(4);
                }
            }
        });
        return reportDamageList;
    }

    /**
     * 新增库存报损
     *
     * @param reportDamage 库存报损
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertReportDamage(ReportDamage reportDamage) {
        List<ReportDamageProduct> damageProductList = reportDamage.getDamageProductList();
        if(CollectionUtils.isEmpty(damageProductList)){
            return AjaxResult.error("报损商品不能为空");
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        reportDamage.setDeptId(loginUser.getDeptId());
        reportDamage.setReportDamageNo(RedisCode.getCode("BS"));
        reportDamage.setCreateTime(DateUtils.getNowDate());
        reportDamage.setCreateBy(loginUser.getUserId());
        reportDamage.setTenantId(loginUser.getTenantId());
        if(reportDamage.getStatus()==2&&iAuditProcessService.verifyProcess(2)){
            reportDamage.setStatus(3);
        }
        int insertReportDamage = reportDamageMapper.insertReportDamage(reportDamage);
        if(insertReportDamage>0){
            damageProductList.stream().forEach(i-> {
                i.setReportDamageId(reportDamage.getId());
                if(reportDamage.getReportDamageReason()==1&&i.getProcessItemId()!=null){
                    iProcessOrderItemService.updateProcessOrderItemById(i.getProcessItemId(),10);
                }
            });
            boolean savedBatch = iReportDamageProductService.saveBatch(damageProductList);
            if(!savedBatch){
                throw new ServiceException("新增报损单失败");
            }
            if(reportDamage.getStatus()==2){
                dataDamageProduct(damageProductList,reportDamage);
            }
            if(reportDamage.getStatus()==3) {
                //发起审批
                AuditInfoDto auditInfoDto = new AuditInfoDto(2, reportDamage.getId().toString(),1);
                Boolean processInstance = processInstanceService.insertProcessInstance(auditInfoDto);
                if (!processInstance) {
                    return AjaxResult.error("发起审批失败");
                }
            }
        }
        return insertReportDamage>0? AjaxResult.success("新增成功"):AjaxResult.error("新增失败");
    }

    /**
     * 修改库存报损
     *
     * @param reportDamage 库存报损
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateReportDamage(ReportDamage reportDamage) {
        List<ReportDamageProduct> damageProductList = reportDamage.getDamageProductList();
        if(CollectionUtils.isEmpty(damageProductList)){
            return AjaxResult.error("报损商品不能为空");
        }
        if(reportDamage.getId()==null){
            return AjaxResult.error("参数id不能为空");
        }
        ReportDamage byId = this.getById(reportDamage.getId());
        if(Objects.isNull(byId)){
            return AjaxResult.error("报损信息不存在");
        }
        //报损状态
        Integer status = byId.getStatus();
        reportDamage.setUpdateTime(DateUtils.getNowDate());
        reportDamage.setUpdateTime(DateUtils.getNowDate());
        reportDamage.setUpdateBy(SecurityUtils.getUserId());
        if(reportDamage.getStatus()==2&&iAuditProcessService.verifyProcess(2)){
            reportDamage.setStatus(3);
        }
        int updateReportDamage = reportDamageMapper.updateReportDamage(reportDamage);
        if(updateReportDamage>0){
            //删除更新前调拨数据
            iReportDamageProductService.deleteReportDamageProductById(reportDamage.getId());
            damageProductList.stream().forEach(i-> {
                i.setReportDamageId(reportDamage.getId());
            });
            boolean savedBatch = iReportDamageProductService.saveBatch(damageProductList);
            if(!savedBatch){
                throw new ServiceException("新增报损单失败");
            }
            if(reportDamage.getStatus()==2){
                reportDamage.setCreateBy(SecurityUtils.getUserId());
                reportDamage.setDeptId(reportDamage.getDeptId());
                dataDamageProduct(damageProductList,reportDamage);
            }
            if(reportDamage.getStatus()==3 && status!=4) {
                //发起审批
                AuditInfoDto auditInfoDto = new AuditInfoDto(2, reportDamage.getId().toString(),1);
                Boolean processInstance = processInstanceService.insertProcessInstance(auditInfoDto);
                if (!processInstance) {
                    return AjaxResult.error("发起审批失败");
                }
            }
            if(status==4){//重新发起
                //发起审批
                AuditInfoDto auditInfoDto = new AuditInfoDto(2, reportDamage.getId().toString(),2);
                Boolean processInstance = processInstanceService.insertProcessInstance(auditInfoDto);
                if (!processInstance) {
                    return AjaxResult.error("发起审批失败");
                }
            }
        }
        return updateReportDamage>0? AjaxResult.success("修改成功"):AjaxResult.error("修改失败");
    }
    /**
     * 处理商品数据
     * @param damageProductList
     * @param reportDamage
     */
    public void dataDamageProduct(List<ReportDamageProduct> damageProductList, ReportDamage reportDamage){
        //报损流水
        List<PurchaseProduct> reportDamageFlowList=new ArrayList<>();

        damageProductList.stream().forEach(i->{
            PurchaseProduct queryProductParam = new PurchaseProduct();
            BeanUtils.copyProperties(i,queryProductParam);
            List<PurchaseProduct> purchaseProductList = purchaseProductMapper.getListByParam(queryProductParam);
            List<PurchaseProduct> purchaseProducts = iRepertoryFlowService.convertFlowData(purchaseProductList, i.getReportDamageNum(), reportDamage.getReportDamageNo(),i.getId());
            purchaseProducts.stream().forEach(s->s.setRemark(i.getRemark()));
            reportDamageFlowList.addAll(purchaseProducts);
            if(reportDamage.getReportDamageReason()==1&&i.getProcessItemId()!=null){
                iProcessOrderItemService.updateProcessOrderItemById(i.getProcessItemId(),10);
            }
        });
        if(CollectionUtils.isEmpty(reportDamageFlowList)) {
            throw new ServiceException("报损商品暂无可用库存");
        }
        for(PurchaseProduct purchaseProduct:reportDamageFlowList){
            //仓库所属部门
            Warehouse warehouse = iWarehouseService.getById(purchaseProduct.getWarehouseId());
            if(Objects.isNull(warehouse)){
                throw new ServiceException("调拨失败--仓库"+warehouse.getWarehouseName()+"不存在");
            }
            purchaseProduct.setPurchaseNumber(reportDamage.getReportDamageNo());
            purchaseProduct.setDeptId(warehouse.getDeptId());
            purchaseProduct.setTenantId(reportDamage.getTenantId());
            purchaseProduct.setCreateBy(reportDamage.getCreateBy());
            purchaseProduct.setInventoryQuantity(purchaseProduct.getInventoryQuantity());
            purchaseProduct.setTenantId(reportDamage.getTenantId());
            purchaseProduct.setRelevancePurchaseId(purchaseProduct.getPurchaseId());
            purchaseProduct.setCreateBy(reportDamage.getCreateBy());
            purchaseProduct.setCreateTime(new Date());
        }
        if(CollectionUtils.isEmpty(reportDamageFlowList)) {
            throw new ServiceException("报损失败");
        }
        boolean saveBatch = iRepertoryFlowService.saveRepertoryFlow(reportDamageFlowList, 2, 9);
        if (!saveBatch) {
            throw new ServiceException("报损失败");
        }
    }
    /**
     * 批量删除库存报损
     *
     * @param ids 需要删除的库存报损主键
     * @return 结果
     */
    @Override
    public int deleteReportDamageByIds(Long[] ids) {
        return reportDamageMapper.deleteReportDamageByIds(ids);
    }

    /**
     * 删除库存报损信息
     *
     * @param id 库存报损主键
     * @return 结果
     */
    @Override
    public int deleteReportDamageById(Long id) {
        return reportDamageMapper.deleteReportDamageById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult reportDamageAudit(AuditDto auditDto) {
        ReportDamage reportDamage = reportDamageMapper.selectById(Long.parseLong(auditDto.getBizNo()));
        if(Objects.isNull(reportDamage)){
            return AjaxResult.error("审核失败");
        }
        auditDto.setBizType(2);
        int updateAuditInfo = processInstanceService.updateProcessInstance(auditDto);
        if(updateAuditInfo== AuditInfoServiceImpl.FINAL_NODE){//最后节点
            List<ReportDamageProduct> damageProductList = iReportDamageProductService.list(new QueryWrapper<ReportDamageProduct>().eq("report_damage_id", reportDamage.getId()));
            dataDamageProduct(damageProductList,reportDamage);
            //完成报损
            reportDamage.setStatus(2);
            reportDamage.setUpdateBy(SecurityUtils.getUserId());
            reportDamage.setUpdateTime(new Date());
            reportDamageMapper.updateReportDamage(reportDamage);
        }
        if(updateAuditInfo== AuditInfoServiceImpl.FIRST_NODE){//重新发起
            //审核未通过
            reportDamage.setStatus(4);
            reportDamage.setUpdateBy(SecurityUtils.getUserId());
            reportDamage.setUpdateTime(new Date());
            reportDamageMapper.updateReportDamage(reportDamage);
        }
        return AjaxResult.success("操作成功");
    }

    @Override
    public List<ProcessingReportDamageVo> getProcessingReportDamageInfo(Long id) {
        return baseMapper.getProcessingReportDamageInfo(id);
    }
}
